﻿using System;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
using Newtonsoft.Json;
using Pyramid.Models;
using Pyramid.Security;
using Pyramid.Tools;

namespace Pyramid.Bll
{
	public class AccountHelper : BllBase
	{

		public static AccountHelper NewInstance
		{
			get { return new AccountHelper(); }
		}

		#region query

		public IQueryable<Account> Query(AccountQueryModel model)
		{
			var accounts = Db.Accounts.AsQueryable();
			if (!string.IsNullOrWhiteSpace(model.Keywords))
			{
				var key = model.Keywords.Trim();
				accounts = accounts.Where(x => x.UserId.Contains(key) || x.FullName.Contains(key) || x.ExtInfoName.Contains(key));
			}
			if (model.UserType.HasValue)
			{
				accounts = accounts.Where(x => x.UserType == model.UserType.Value);
			}
			return accounts;
		}

		#endregion

		#region insert or update

		public bool InsertOrUpdate4Staff(int staffId, Account model, int[] selectedRoleIds)
		{
			var staff = Db.Staves.SingleOrDefault(x => x.Id == staffId);
			if (staff == null)
			{
				Alert("员工档案信息已丢失，请联系管理员！");
				return false;
			}

			model.ExtInfoId = staffId;
			model.ExtInfoName = staff.FullName;
			model.UserType = (int) UserTypes.Staff;

			if (InsertOrUpdate(model, selectedRoleIds))
			{
				staff.UserId = model.UserId;
				Db.SaveChanges();
				return true;
			}

			return false;
		}

		public bool InsertOrUpdate4AdminCenter(int adminCenterId, Account model, int[] selectedRoleIds)
		{
			var ac = Db.AdminCenters.SingleOrDefault(x => x.Id == adminCenterId);
			if (ac == null)
			{
				Alert("管理中心档案信息已丢失，请联系管理员！");
				return false;
			}

			model.ExtInfoId = adminCenterId;
			model.ExtInfoName = ac.Name;
			model.UserType = (int) UserTypes.AdminCenter;

			if (InsertOrUpdate(model, selectedRoleIds))
			{
				ac.UserId = model.UserId;
				Db.SaveChanges();
				return true;
			}

			return false;
		}

		public bool InsertOrUpdate4MemberCenter(int memberCenterId, Account model, int[] selectedRoleIds)
		{
			var center = Db.MemberCenters.SingleOrDefault(x => x.Id == memberCenterId);
			if (center == null)
			{
				Alert("管理中心档案信息已丢失，请联系管理员！");
				return false;
			}

			model.ExtInfoId = memberCenterId;
			model.ExtInfoName = center.Name;
			model.UserType = (int) UserTypes.MemberCenter;

			if (InsertOrUpdate(model, selectedRoleIds))
			{
				center.UserId = model.UserId;
				Db.SaveChanges();
				return true;
			}

			return false;
		}

		public bool InsertOrUpdate4Customer(int customerId, Account model, int[] selectedRoleIds)
		{
			var customer = Db.Customers.SingleOrDefault(x => x.Id == customerId);
			if (customer == null)
			{
				Alert("管理中心档案信息已丢失，请联系管理员！");
				return false;
			}

			model.ExtInfoId = customerId;
			model.ExtInfoName = customer.FullName;
			model.UserType = (int) UserTypes.Customer;

			if (InsertOrUpdate(model, selectedRoleIds))
			{
				customer.UserId = model.UserId;
				Db.SaveChanges();
				return true;
			}

			return false;
		}

		/// <summary>
		/// 添加或更新账号
		/// </summary>
		public bool InsertOrUpdate(Account model, int[] selectedRoleIds)
		{
			if (Db.Accounts.Any(x => x.Id != model.Id && x.UserId == model.UserId))
			{
				Alert("登录账号已存在，请更换其它！");
				return false;
			}

			model.Roles = new Collection<Role>();

			if (selectedRoleIds != null && selectedRoleIds.Length > 0)
			{
				var selectedRoles = Db.Roles.ToList().Where(x => selectedRoleIds.Contains(x.RoleId));
				foreach (var role in selectedRoles)
				{
					model.Roles.Add(role);
				}
			}

			//加密保存密码
			model.Password = Password.Encryption(model.Password);

			if (model.Id == 0)
			{
				Db.Accounts.Add(model);
			}
			else
			{
				Db.Entry(model).State = EntityState.Modified;
			}
			Db.SaveChanges();

			return true;
		}

		#endregion

		#region login related

		public void LoginAction(Account account, bool isPersistent, HttpResponseBase response)
		{
			var userInfo = new CustomPrincipal
				{
					UserId = account.UserId,
					Identity = new GenericIdentity(account.UserId),
					UserType = (UserTypes) account.UserType,
					FullName = account.FullName,
					ExtInfoId = account.ExtInfoId,
					ExtInfoName = account.ExtInfoName
				};

			var userData = JsonConvert.SerializeObject(userInfo);
			var authTicket = new FormsAuthenticationTicket(1, account.UserId, DateTime.Now, DateTime.Now.AddMinutes(20), isPersistent, userData);
			var encTicket = FormsAuthentication.Encrypt(authTicket);
			var facookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
			response.Cookies.Add(facookie);
		}

		public CustomPrincipal GetUser(HttpContextBase httpContext)
		{
			var user = httpContext.User as CustomPrincipal;
			if (user != null) return user;
			var facookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
			if (facookie == null) return null;
			var authTicket = FormsAuthentication.Decrypt(facookie.Value);
			if (authTicket == null) return null;
			user = JsonConvert.DeserializeObject<CustomPrincipal>(authTicket.UserData);
			user.Identity = new GenericIdentity(user.UserId);
			httpContext.User = user;
			return user;
		}

		#endregion
	}
}